package net.xby1993.eventbus;

import java.awt.EventQueue;

final class HandlerPoster  {

    private final PendingPostQueue queue;
    private final int maxMillisInsideHandleMessage;
    private final EventBus eventBus;
    private boolean handlerActive;
	private PendingPost pendingPost;
//
    HandlerPoster(EventBus eventBus,  int maxMillisInsideHandleMessage) {
        this.eventBus = eventBus;
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();
    }

    void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!handlerActive) {
                handlerActive = true;
                handleMessage();
            }
        }
    }

    public void handleMessage() {
        boolean rescheduled = false;
        try {
            long started = System.currentTimeMillis();
            while (true) {
                pendingPost = queue.poll();
                if (pendingPost == null) {
                    synchronized (this) {
                        // Check again, this time in synchronized
                        pendingPost = queue.poll();
                        if (pendingPost == null) {
                            handlerActive = false;
                            return;
                        }
                    }
                }
                EventQueue.invokeLater(new Runnable(){
					@Override
					public void run() {
						// TODO Auto-generated method stub
						eventBus.invokeSubscriber(pendingPost);
					}              	
                });
                
                long timeInMethod = System.currentTimeMillis() - started;
                if (timeInMethod >= maxMillisInsideHandleMessage) {
                	 rescheduled = false;
                        throw new EventBusException("Could not send handler message");                   
                   
                }
            }
        } finally {
            handlerActive = false;
        }
    }
}